<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  
  <meta name="generator" content="Hugo 0.98.0" />

  
  <meta name="description" content="走在通往幸福的路上">
  

  
  <link rel="apple-touch-icon" sizes="180x180" href="https://blog.v5u.win/apple-touch-icon.png">

  
  <link rel="icon" type="image/png" sizes="32x32" href="https://blog.v5u.win/favicon-32x32.png">

  
  <link rel="icon" type="image/png" sizes="16x16" href="https://blog.v5u.win/favicon-16x16.png">

  
  <link rel="manifest" href="https://blog.v5u.win/site.webmanifest">

  
  <link rel="mask-icon" href="https://blog.v5u.win/safari-pinned-tab.svg" color="">

  <meta name="msapplication-TileColor" content="">

  <meta name="theme-color" content="">

  
  <link rel="stylesheet" href="https://blog.v5u.win/css/bootstrap.min.css" />

  
  <title>iOS NSNotificationCenter自管理内存 | 为吾优</title>
  

  <style>
body {
  min-width: 300px;
}

.custom-navbar {
  margin-bottom: 1em;
  height: 60px;
}

.custom-navbar a {
  display: inline-block; 
  padding: 18px 0;
  margin-right: 1em; 
  font-weight: bold; 
}

.custom-navbar a:hover,
.custom-navbar a:focus {
  text-decoration: none; 
}

@media print {
  .custom-navbar {
    display: none;
  }
}

article {
  padding-bottom: 1em;
}

img {
  max-width: 100%;
}


body {
  background-color: #fff;
}



body {
  color: #212529;
}



a {
  color: #007bff;
}



a:hover,
a:focus {
  color: #0056b3;
}



.custom-navbar {
  background-color: #212529;
}



.custom-navbar a {
  color: rgba(255,255,255,.75);
}



.custom-navbar a:hover,
.custom-navbar a:focus {
  color: rgba(255,255,255,1);
}



.container {
  max-width: 800px;
}





</style>
</head>

<body>
  <nav class="custom-navbar">
  <div class="container">
    
    <a href="/">文章</a>
    
    <a href="/tags/">标签</a>
    
    <a href="/about/">关于</a>
    
    <a href="/index.xml">RSS</a>
    
  </div>
</nav>
  
  <div class="container">
    <article>
      <h1>iOS NSNotificationCenter自管理内存</h1>
<h3 id="我找到解决nsnotificationcenter通知中心自管理内存的方案了">我找到解决NSNotificationCenter通知中心自管理内存的方案了</h3>
<p>我们知道OC中 使用观察者模式 会对观察者进行强引用，导致循环引用，内存无法释放，也就是对象无法走到dealloc这一步。</p>
<h4 id="那么如何实现一个可以自己管理自己生命周期的的通知中心呢">那么如何实现一个可以自己管理自己生命周期的的通知中心呢？</h4>
<p>要解决这个问题，就需要做到两步：1. 拿到观察者数组 2. 找到一个合适的时机对Observer进行释放。</p>
<p>我想了几天，找到了一个思路，这还是前几天领悟适配器模式后带来的启发。我们知道通知中心是通过维护一个观察者数组来进行广播的，如果要解决通知中心自己释放观察者的行为。我们就需要拿到通知中心管理的观察者数组。可是我查了一下NSNotificationCenter的API，苹果并没有对外暴露可以拿到观察者数组的接口。这个时候有用到适配器模式了，其实想来，对原生类的所有扩展方法，适配器模式都是一个很好的方案，这个方案具有最通用的迁移性。我们可以新建一个类，对NSNotificationCenter进行管理，每次添加观察者的时候addObserver就同时将对象也保持在新类中一个管理数组中，而这个数组使我们可以拿到的。 至于释放时机，其实对于Controller来说还是很好找到的，虽然因为循环引用导致代码不能执行到Dealloc方法，但是页面的退出是不受影响的，所以viewDidDisappear是会执行到的。那么这里就是一个很好的释放时机。为了减少依赖，减少侵入性。最好是以面向切面的方式找到这个释放时机，进行释放。所以可以使用BaseController也可以使用runtime的方法交换的方式，找到viewDidDisappear方法。</p>
<p>至此一个完整的解决方案就出来了，通过适配器模式+面向切面编程解决。</p>

    </article>
  </div>

  
  
  

  
</body>

</html>